package com.hqyj.freemovie.front.test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class ArrayBlockingQueueDemo {
    private final static ArrayBlockingQueue<Cake> queue = new ArrayBlockingQueue<>(10);

    public static void main(String[] args) {
        Thread mother = new Thread(new Producer(queue));
        Consumer c = new Consumer(queue);

        Thread bigSon = new Thread(c, "大林");
        Thread smallSon = new Thread(c, "小林");

        mother.start();
        bigSon.start();
        smallSon.start();

        try {
            mother.join();
            bigSon.join();
            smallSon.join();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        System.out.println("大林吃了：" + Consumer.bigSonNum + "个馒头。");
        System.out.println("小林吃了：" + Consumer.smallSonNum + "个馒头。");
    }
}

class Cake {
    public volatile static AtomicInteger iCount = new AtomicInteger(100);

    public Cake() {
        Cake.iCount.decrementAndGet();
    }

    @Override
    public String toString() {
        return "馒头";
    }
}

/**
 * 生产者线程
 */
class Producer implements Runnable {
    private final ArrayBlockingQueue<Cake> mAbq;

    Producer(ArrayBlockingQueue<Cake> arrayBlockingQueue) {
        this.mAbq = arrayBlockingQueue;
    }

    @Override
    public void run() {
        while (true) {
            if (Cake.iCount.get() <= 0) {
                System.out.println("妈妈100个馒头做完了....");
                break;
            }
            Produce();
        }
    }

    private void Produce() {
        try {
            Cake c = new Cake();
            mAbq.put(c);
            System.out.println("妈妈做一个" + c + ",还剩：" + Cake.iCount.get() + "个馒头。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 消费者线程
 */
class Consumer implements Runnable {

    public static int bigSonNum = 0;
    public static int smallSonNum = 0;
    ;
    private ArrayBlockingQueue<Cake> mAbq;

    Consumer(ArrayBlockingQueue<Cake> arrayBlockingQueue) {
        this.mAbq = arrayBlockingQueue;
    }

    @Override
    public void run() {
        if (Cake.iCount.get() <= 0 && mAbq.isEmpty()) {
            return;
        }
        while (true) {
            if (Cake.iCount.get() <= 0 && mAbq.isEmpty()) {
                break;
            }
            try {
                this.comsume();
                if (Cake.iCount.get() <= 0 && mAbq.isEmpty()) {
                    break;
                }
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private synchronized void comsume() throws InterruptedException {
        if (Cake.iCount.get() <= 0 && mAbq.isEmpty()) {
            return;
        }

        Cake c = mAbq.take();
        String name = Thread.currentThread().getName();
        if ("大林".equals(name)) {
            Consumer.bigSonNum++;
        } else {
            Consumer.smallSonNum++;
        }
        System.out.println(name + "吃了一个" + c + ",还剩：" + Cake.iCount.get() + "个馒头。");


    }
}
